messageTray: Disconnect to global signals on destruction
The global display object has always a longer lifetime than anything
that is initialized from JS, so avoid signals that it may emit to be
handled at later point.
It handles issues such as:
(gnome-shell:2429): Gjs-CRITICAL **: 23:18:35.025: Object
Gjs_ui_messageTray_MessageTray (0x3440ed60), has been already disposed —
impossible to set any property on it.
This might be caused by the object having been destroyed from C code using
something such as destroy(), dispose(), or remove() vfuncs.
== Stack trace for context 0x31073eb0 ==
#0 348db378 i resource:///org/gnome/shell/ui/messageTray.js:1046 (3a8ac3a71f60 @ 104)
#1 348db2d8 i resource:///org/gnome/shell/ui/main.js:277 (3a8ac3a0b100 @ 119)
Seen in: https://gitlab.gnome.org/GNOME/gnome-shell/-/jobs/5846454
Florian Müllner [Thu, 27 Nov 2025 15:29:44 +0000 (16:29 +0100)]
test-tool: Set up GSettings keyfile
Even with a separate XDG_CONFIG_HOME, settings may still be picked
up from the session's dconf instance (although the tool is typically
run through dbus-run-session).
To really ensure that we control the settings, we can force a different
backend. The 'memory' backend would be enough to ensure default values,
however using the 'keyfile' backend means we can also inject non-default
values.
Florian Müllner [Thu, 27 Nov 2025 13:43:43 +0000 (14:43 +0100)]
test-tool: Set up a temporary xdg-home directory
Currently the launched gnome-shell instance uses the regular xdg-home
directories, which means it picks up settings, extensions etc. from
the current user.
Avoid this by pointing the xdg-home dirs to a temporary directory, so
everything that respects the basedir spec runs with a clean slate.
Florian Müllner [Thu, 27 Nov 2025 14:06:12 +0000 (15:06 +0100)]
test-tool: Remove option to upload perf reports
If memory serves well, uploads happened to a server in Owen's living
room. It is doubtful that the server-side still exists anywhere, or
that anyone has uploaded any reports in the last 15 years, so stop
carrying that code around.
Florian Müllner [Thu, 27 Nov 2025 14:41:44 +0000 (15:41 +0100)]
test-tool: Adjust name in --version
The tool was renamed from "perf-tool" a while ago, to reflect
that its purpose has shifted from collecting performance data
to running gnome-shell with scripted tests.
We are using it in overviewControls but the value is not exported.
This caused an issue when the animations are not enabled, since in a
racy way (e.g. only sometimes, depending on the init speed) the value
was undefined, and so we ended up falling back to the default animation
duration time.
In case an actor easing is created without an explicit duration, we
should rely to the default animation that Clutter.Actor.save_easing_state()
sets to 250ms.
This fine in normal use cases, but in case the animations are disabled
the current code skips calling our Clutter.Actor.set_easing_duration()
override, and so we just end up leaving the actor easing time to 250ms,
not respecting the St settings
Carlos Garnacho [Fri, 21 Nov 2025 13:46:03 +0000 (14:46 +0100)]
screenShield: Emit ::screen-lock-shown early with animated fades
If the screen is locked with animatedFade parameter enabled, the
screenShield currently defers the emission of this signal until the
lightbox toggles on. However the lightbox might be prevented from
ever doing that by later input.
If this emission is delayed enough, it will result in ShellDBus
missing the D-Bus timeout for replying to the Lock request, since
it does rely on this signal being emitted in order to reply back.
It does however make sense to keep setting the active state after
the animation, so the inhibitors are synchronized at the point the
lightbox kicks in.
Florian Müllner [Thu, 20 Nov 2025 15:09:44 +0000 (16:09 +0100)]
swipeTracker: Immediately flip delta in RTL locales
The delta is currently flipped in a shared code path, after appending
the unmodified value to the event history. As a result, the calculated
final velocity for touchpad gestures is wrong in RTL locales.
Fix this by modifying the delta immediately when handling the events,
so that all other code operates on the correct values.
Philip Withnall [Tue, 11 Nov 2025 15:31:22 +0000 (15:31 +0000)]
timeLimitsManager: Batch-submit usage records to malcontent-timerd
This was skipped in the first version of parental controls screen time
limits, because we forgot that `RecordUsage()` already allows batch
submission of usage records.
Rework the code to make one D-Bus call rather than O(N) calls.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3958>
The LongPressGesture 'may-recognize' callback in commit 314137c8c was
checking if clicks were inside '_switcherList', but thumbnails shown by
switch-group are siblings of _switcherList, not children.
This caused the gesture to incorrectly identify thumbnail clicks as
'outside' clicks, closing the popup before the click could complete.
Fix by adding a _isActorOutside() helper method that subclasses can
override to check additional containers. AppSwitcherPopup now properly
checks both _switcherList and _thumbnails.
Tested on Ubuntu 25.10 with GNOME Shell 49.0. Confirmed:
- switch-group mouse clicks now work
- switch-applications and switch-windows unaffected
- clicking outside the popup still closes it correctly
- no regressions introduced
Fixes: 314137c8c9 ("switcherPopup: Move to a ClutterGesture for closing the popup") Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8812
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3959>
Adrian Vovk [Thu, 1 May 2025 22:34:52 +0000 (18:34 -0400)]
main: Register session with GDM on startup
When no monitor is connected, gnome-shell starts but never emits
`startup-prepared` nor `startup-complete`. As a result, GDM never
detects that the shell has launched and plymouthd remains running,
preventing the system from reaching graphical.target.
Ensure that registerSessionWithGDM() is called even when no monitor
is connected, so GDM can terminate plymouthd and allow the system to
reach graphical.target properly.
Part of https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/285
timeLimitsManager: Integrate with malcontent and lock when limit reached
Lock the screen when screen time limit is reached in a child session,
which required extending the existing TimeLimitsManager functionality to
include the parental controls session limits.
TimeLimitsDispatcher was also adjusted to take into account parental
controls session limits before making any user facing changes.
timeLimitsManager: Rename function updating state machine
Rename _updateSettings function to _updateStateMachine, since that's
what the function actually does, starting or stopping the machine
depending on the 'history-enabled' GSetting. Moreover, in the future
we'll take into account parental controls settings too, so renaming the
function to be more generic will avoid confusion later on.
tests/unit: Add a helper method in TimeLimitsManager
Currently we create a new `TimeLimitsManager` for each of the unit tests
for testing the wellbeing screen time limit, with the same parameters.
Rather than having to repeat the entire constructor call multiple times,
factor it out into a helper method on the `TestHarness`. There is no
difference in functionality itself.
Add org.freedesktop.MalcontentTimer1.Child interface for accessing the
screen time and app usage periods for current user account. Currently
unused, will provide necessary functionality when integrating parental
controls session limits with TimeLimitsManager.
parentalControlsManager: Add support for session limits
Add ability to check if session limits are enabled for users using API
introduced in malcontent 0.14.0. The `get_session_limits_async` function
is actually available since 0.5.0, but the signal
`session-limits-changed` was only introduced in 0.14.0, so check for
function `get_daily_limit` which was introduced in 0.14.0 to be sure
we're using correct version. This allows us to keep filtering apps, even
if the library version doesn't fully support session limits.
Will be used in the future to integrate parental controls session
limits.
Carlos Garnacho [Wed, 8 Oct 2025 18:36:39 +0000 (20:36 +0200)]
grabHelper: Port to using ClickGesture to dismiss
There's a few things we don't need anymore here. We don't
need holding on the captured events until button release
anymore, and we don't need to track crossing events outside
the grab as those will not get emitted as usual. This allows
for a few simplifications in handling the events for the
GrabHelper.
Carlos Garnacho [Wed, 8 Oct 2025 17:37:04 +0000 (19:37 +0200)]
searchController: Maybe reset search using a click gesture
We don't want the gesture to consume input though, we just want
it as a trigger on click, so use the ::may-recognize signal to
hook this "reset, but passthrough" behavior on.
We are currently still using eslint 8.x which has been unsupported
for quite a while. Update the ci-run-eslint script to a verison
that uses the supported eslint 9.x.
There's no reason why this is not the case, given that these tests are
running in completely separated environments, so they are safe to run in
parallel
overviewControls: Disconnect signals on destruction
While we are not getting errors and the ControlsManger is normally always
alive, during destruction we could still get events from other objects
that are still alive, so disconnect them all
workspaceThumbnail: Track later hiding drop placeholder
When closing the shell during a relayout we are getting this error:
(gnome-shell:2559407): Gjs-CRITICAL **: 06:57:21.765: Object St.Bin,
has been already disposed — impossible to access it.
This might be caused by the object having been destroyed from C code
using something such as destroy(), dispose(), or remove() vfuncs.
== Stack trace for context 0x60991609b710 ==
#0 b resource:///org/gnome/shell/ui/workspaceThumbnail.js:1334 (5e050636fb0 @ 17)
#1 i resource:///org/gnome/shell/ui/main.js:279 (30c932d102e0 @ 119)
This is because the later we added is running even when not needed (e.g
when the placeholder is not visible already), but also because we may
run the later callback after the parent has been destroyed.
While it only starts the shell, waits for startup being completed and
return, it's relevant to check the shutdown process in this phase and
to ensure that we cleanup things as expected
We (I) changed the test job to use a different path in commit 342d7ab34,
but the artifacts path was not adjusted :(
Fixes: 342d7ab34a ("ci: Start with a fresh build dir to ensure test dependencies are correct")
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3945>
Sebastian Wick [Mon, 20 Oct 2025 11:38:37 +0000 (13:38 +0200)]
brightnessManager: Use slider as bias when auto brightness is being used
The code previously tried to ensure that the sliders were disabled when
auto brightness was active, and determine the brightness just from the
auto brightness target we get from g-s-d.
It turns out that users do want to still have some control over the
brightness, even if auto brightness is active.
The slider is now being used as a bias for the auto brightness target
instead.
This also means that we can drop the BrightnessScale::locked property.
Sebastian Wick [Thu, 30 Oct 2025 10:43:19 +0000 (11:43 +0100)]
brightnessManager: Propagate any attempted brightness change
The BrightnessScale was trying to be smart by not notifying changes of
its value when an action on it (stepUp, stepDown, cycleUp, set value)
resulted in no change.
It turns out that users do want to see an OSD even when their action
resulted in no change.
Alessandro Bono [Thu, 30 Oct 2025 10:47:17 +0000 (11:47 +0100)]
loginManager: Use systemd session auto object to get session ID
Relying on the Display property is buggy when the gdm user spawns more than
one gnome-shell instance.
```
$ loginctl
SESSION UID USER SEAT LEADER CLASS TTY IDLE SINCE
11 42 gdm - 11778 manager-early - no -
c20 42 gdm seat0 34313 greeter tty1 yes 17h ago
c21 42 gdm - 34938 greeter - no -
c22 42 gdm - 35693 greeter - no -
```
From the logs:
```
$ journalctl -b | grep "Will monitor"
[...]
Oct 29 15:14:59 gnome-shell[34961]: Will monitor session c20
Oct 29 15:22:57 gnome-shell[35716]: Will monitor session c20
Oct 29 15:22:58 gnome-shell[35716]: Will monitor session c20
```
Use the systemd session auto object for getting the session id. We can't return
directly the session proxy created from it because it won't emit signals. From
the documentation[1]:
```
Signals are only emitted on objects referencing a specific session ID not on the
"/org/freedesktop/login1/session/self" or "/org/freedesktop/login1/session/auto"
convenience objects, as they can only be dereferenced relative to a method caller.
```
Sebastian Keller [Wed, 29 Oct 2025 10:09:02 +0000 (11:09 +0100)]
osk-layouts: Drop comma key from de-extended and at-extended layouts
The row containing that key was one key too long, which was causing
misalignment. The comma key is not shown in the us-extended layout
either and is available via long press on the dot key or via ?123,
making it the best candidate to remove from these layouts.
This is not needed anymore now that e8d73262 has been reverted and it
was causing problems in X11 sessions, such as when switching from the
4th layout to the 3rd using the keyboard layout menu.
The commit was causing freezes when changing layouts in some situations
and not all of these were adressed by f643915b, such as when switching
from the 3rd to the 4th layout using a xkb shortcut in the X11 session
with 4 layouts.
It was also breaking the order of switching layouts using modifier-only
xkb shortcuts to switch to the next group, which it caused to advance
multiple groups because of the shortcut being handled via both
_modifiersSwitcher() and _layoutGroupChanged().
Further it was possible for _layoutGroupChanged() to trigger an error
due to the locale layout added by _buildGroupStrings() at the end of the
xkb layout list being accessible via the xkb shortcuts. That layout was
not present in _inputSources, leading to "is" being undefined.
Florian Müllner [Tue, 21 Oct 2025 18:12:59 +0000 (20:12 +0200)]
tools: Symlink node_modules in project root
NPM assumes quite strongly that it manages the project as a
whole and its package/lock files are located in the project
root.
While we somehow managed to keep the npm tooling in a subfolder,
this comes at the cost of breaking imports of additional modules.
This will become relevant when we update eslint to a supported
version, as we want to keep using the `junit` formatter in CI,
which has now been split out into a separate module.
So bite the bullet and make the node_modules folder available in
the project root.
On the plus side, having the node_modules folder in the project
root allows language servers in IDEs/editors to pick it up.
Florian Müllner [Thu, 23 Oct 2025 12:06:08 +0000 (14:06 +0200)]
tools: Pin git node modules
Both changes in the config (like new/changes rules) and the eslint wrapper
(like updating to eslint 9.x) could require changes on the shell side, and
therefore require conscious update rather than randomly breaking the CI.
Carlos Garnacho [Thu, 23 Oct 2025 18:56:10 +0000 (20:56 +0200)]
keyboardManager: Update layout index before keymap
Unfortunately, layouts and keymaps are not considered atomic data
even though they are closely related. Furthermore, these are async
operations that are not immediate to apply, and each of them result
in a plethora of updates down in Mutter (layout group being a subset
of keymaps).
Doing things in the current order, these updates do result in a
feedback loop, since the layout index is not changed altogether with
the keymap, but the keymap update is also seen as a layout change.
Even though it still does result in unnecessary intermediate updates,
changing the layout index first avoids the feedback loop, since it
will already match with the expectations after the ClutterKeymap is
updated.
This fixes deadlocked shell when using xkb options that trigger layout
changes through the ISO_Next_Group key emission, when the group change
also triggered a keymap update (e.g. moving to a different group
per KeyboardManager.MAX_LAYOUTS_PER_GROUP limits).
This does not fix being able to switch between all layouts, when
there is more than one group. This will be fixed in later commits.
Sebastian Keller [Sat, 25 Oct 2025 11:03:55 +0000 (13:03 +0200)]
keyboard: Don't move window when it got unmanaged during shift animation
When a window with a text-entry at the bottom that had triggered the OSK
and was shifted up to avoid overlapping the OSK is closed right after
losing keyboard focus, this results in a crash. The focus loss triggers
the animation to move the window actor back into its original position,
which moves the underlying window when finished. That however will fail
when the window has been unmanaged and some of the underlying resources
have already been destroyed while the animation was playing.
Florian Müllner [Tue, 21 Oct 2025 22:57:26 +0000 (00:57 +0200)]
systemActions: Don't log error when cancelled
If the logout/reboot/shutdown actions are available, we expect them
to succeed. Unfortunately that changed in the light of systemd
inhibitors (that we don't know about in the shell, and that prevent
those actions now).
While it would be good to fix the underlying issue, we can at least
improve the error reporting in that case and not log the error when
the operation was cancelled: We don't know the underlying reason,
unlike gnome-session which should have logged a more helpful message.
Florian Müllner [Fri, 24 Oct 2025 11:39:37 +0000 (13:39 +0200)]
js: Use const declarations where possible
It is useful to indicate clearly that a value is read-only, and
we have already been doing so for new code for a long time. But
in order to actually enforce this, we have to adjust all existing
code.
Luckily the change is trivial enough to do (thanks to `eslint --fix`),
so do it now.